package com.ytjj.qmyx.supplychain.api.ceb.controller;

import com.alibaba.fastjson.JSONObject;
import com.ytjj.qmyx.supplychain.api.ceb.config.CebParamConfig;
import com.ytjj.qmyx.supplychain.api.ceb.model.*;
import com.ytjj.qmyx.supplychain.api.ceb.model.request.CebDataUploadReq;
import com.ytjj.qmyx.supplychain.api.ceb.model.request.CebOrderReturnReq;
import com.ytjj.qmyx.supplychain.api.ceb.model.request.CebUpdateSendStatusReq;
import com.ytjj.qmyx.supplychain.api.ceb.model.request.CebUpdateSignReq;
import com.ytjj.qmyx.supplychain.api.ceb.model.response.CebDataUploadResp;
import com.ytjj.qmyx.supplychain.api.ceb.model.response.CebUnSendDataResp;
import com.ytjj.qmyx.supplychain.api.ceb.model.response.CebUnSignDataResp;
import com.ytjj.qmyx.supplychain.api.ceb.util.CebUtil;
import com.ytjj.qmyx.supplychain.common.api.CommonPage;
import com.ytjj.qmyx.supplychain.common.api.CommonResult;
import com.ytjj.qmyx.supplychain.common.enums.CebOrderSendStatusEnums;
import com.ytjj.qmyx.supplychain.common.enums.CebUploadReqSignStatusEnums;
import com.ytjj.qmyx.supplychain.common.enums.CebUploadReqStatusEnums;
import com.ytjj.qmyx.supplychain.common.model.request.CebOrderRequest;
import com.ytjj.qmyx.supplychain.common.model.request.CebUploadReqRequest;
import com.ytjj.qmyx.supplychain.common.model.response.CebOrderGoodsResponse;
import com.ytjj.qmyx.supplychain.common.model.response.CebOrderResponse;
import com.ytjj.qmyx.supplychain.common.model.response.CebUploadReqResponse;
import com.ytjj.qmyx.supplychain.mapper.entity.CebUploadReq;
import com.ytjj.qmyx.supplychain.service.CebOrderService;
import com.ytjj.qmyx.supplychain.service.CebUploadReqService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@RequestMapping("/ceb")
public class CebController {
    @Autowired
    private CebParamConfig cebParamConfig;

    @Autowired
    private CebOrderService cebOrderService;

    @Autowired
    private CebUploadReqService cebUploadReqService;

    /**
     * 接收海关发起的支付相关实时数据获取请求
     * @param openReq
     * @return
     */
    @PostMapping("/upload/req")
    public CebDataUploadResp uploadReq(@RequestParam String openReq) {
        log.info("openReq={}", openReq);
        CebDataUploadReq cebDataUploadReq = JSONObject.parseObject(openReq,CebDataUploadReq.class);
        CebOrderResponse cebOrder=cebOrderService.findByOrderNo(cebDataUploadReq.getOrderNo());
        //订单存在
        if(cebOrder!=null){
            CebUploadReq cebUploadReq = new CebUploadReq();
            cebUploadReq.setCreateTime(new Date());
            cebUploadReq.setOrderNo(cebDataUploadReq.getOrderNo());
            cebUploadReq.setSessionId(cebDataUploadReq.getSessionID());
            cebUploadReq.setStatus(CebUploadReqStatusEnums.UN_UPLOAD.getStatus());
            cebUploadReq.setSignStatus(CebUploadReqSignStatusEnums.UN_SIGN.getStatus());
            cebUploadReq.setServiceTime(cebDataUploadReq.getServiceTime());
            cebUploadReqService.saveCebUploadReq(cebUploadReq);
        }
        CebDataUploadResp cebDataUploadResp=new CebDataUploadResp();
        cebDataUploadResp.setCode("10000");
        cebDataUploadResp.setMessage("");
        cebDataUploadResp.setServiceTime(System.currentTimeMillis());
        return cebDataUploadResp;
    }

    /**
     * 签名客户端获取待签名数据列表
     * @return
     */
    @GetMapping("/client/getUnSignDataList")
    public CommonResult getUnSignDataList() {
        log.info("getUnSignDataList");
        CebUploadReqRequest cebUploadReqRequest = new CebUploadReqRequest();
        cebUploadReqRequest.setStatus(CebUploadReqStatusEnums.UN_UPLOAD.getStatus());
        cebUploadReqRequest.setSignStatus(CebUploadReqSignStatusEnums.UN_SIGN.getStatus());
        cebUploadReqRequest.setPageNum(1);
        cebUploadReqRequest.setPageSize(5);
        CommonPage commonPage = cebUploadReqService.getCebUploadReqList(cebUploadReqRequest);
        List<CebUploadReqResponse> cebUploadReqResponseList = commonPage.getList();
        List<CebUnSignDataResp> cebUnSignDataRespList = cebUploadReqResponseList.stream().map(item -> {
            CebUnSignDataResp cebUnSignDataResp = new CebUnSignDataResp();
            cebUnSignDataResp.setSessionId(item.getSessionId());
            cebUnSignDataResp.setData(CebUtil.getCebSignData(item,cebOrderService.findByOrderNo(item.getOrderNo()),cebParamConfig));
            return cebUnSignDataResp;
        }).collect(Collectors.toList());
        return CommonResult.success(cebUnSignDataRespList);
    }
    /**
     * 签名客户端更新签名值
     * @param cebUpdateSignReq
     * @return
     */
    @PostMapping("/client/updateSign")
    public CommonResult updateSign(@RequestBody CebUpdateSignReq cebUpdateSignReq) {
        log.info("cebUpdateSignReq={}", JSONObject.toJSONString(cebUpdateSignReq));
        CebUploadReqResponse cebUploadReqResponse=cebUploadReqService.findBySessionId(cebUpdateSignReq.getSessionId());
        //请求存在
        if(cebUploadReqResponse!=null){
            return cebUploadReqService.updateSignStatus(cebUploadReqResponse.getId(),CebUploadReqSignStatusEnums.SIGNED.getStatus(),cebUpdateSignReq.getSignValue());
        }else{
            return CommonResult.failed("更新签名失败，请求不存在！");
        }

    }

    /**
     * 获取待推送到海关的电子订单
     * @return
     */
    @GetMapping("/client/getCebOrderList")
    public CommonResult getCebOrderList() {
        CebOrderRequest cebOrderRequest = new CebOrderRequest();
        cebOrderRequest.setPageNum(1);
        cebOrderRequest.setPageSize(10);
        cebOrderRequest.setSendStatus(CebOrderSendStatusEnums.UN_SEND.getStatus());
        CommonPage commonPage = cebOrderService.getCebOrderList(cebOrderRequest);
        List<CebOrderResponse> cebOrderResponseList=commonPage.getList();
        List<CEB311MessageVO> ceb311MessageList = cebOrderResponseList.stream().map(item -> {
            CEB311MessageVO ceb311MessageVO=CebUtil.buildCEB311Message(item,cebParamConfig);
            return ceb311MessageVO;
        }).collect(Collectors.toList());
        return CommonResult.success(ceb311MessageList);
    }

    /**
     * 修改电子订单发送状态
     * @param cebUpdateSendStatusReq
     * @return
     */
    @PostMapping("/client/updateCebOrderSendStatus")
    public CommonResult updateCebOrderSendStatus(@RequestBody CebUpdateSendStatusReq cebUpdateSendStatusReq) {
        log.info("cebUpdateSendStatusReq={}", JSONObject.toJSONString(cebUpdateSendStatusReq));
        String sendStatusDesc=CebOrderSendStatusEnums.getStatusDesc(cebUpdateSendStatusReq.getSendStatus());
        if(null==sendStatusDesc){
            return CommonResult.failed("更新电子订单状态失败，状态码错误！");
        }
        Date sendTime = null;
        if(CebOrderSendStatusEnums.SUCCESS.getStatus().equals(cebUpdateSendStatusReq.getSendStatus())){
            sendTime = new Date();
        }
        return cebOrderService.updateSendStatus(cebUpdateSendStatusReq.getOrderNo(),cebUpdateSendStatusReq.getSendStatus(),sendTime);
    }

    /**
     * 保存电子订单海关回执
     * @param cebOrderReturnReq
     * @return
     */
    @PostMapping("/client/saveCebOrderReturn")
    public CommonResult saveCebOrderReturn(@RequestBody CebOrderReturnReq cebOrderReturnReq) {
        log.info("cebOrderReturnReq={}", JSONObject.toJSONString(cebOrderReturnReq));
        return cebOrderService.updateCebOrderReturn(cebOrderReturnReq.getOrderNo(),cebOrderReturnReq.getReturnStatus(),cebOrderReturnReq.getReturnTime(),cebOrderReturnReq.getReturnInfo());
    }

    /**
     * 获取已加签未上传的数据列表
     * @return
     */
    @GetMapping("/client/getSignedUnSendDataList")
    public CommonResult getSignedUnSendDataList() {
        log.info("getSignedUnSendDataList");
        CebUploadReqRequest cebUploadReqRequest = new CebUploadReqRequest();
        cebUploadReqRequest.setStatus(CebUploadReqStatusEnums.UN_UPLOAD.getStatus());
        cebUploadReqRequest.setSignStatus(CebUploadReqSignStatusEnums.SIGNED.getStatus());
        cebUploadReqRequest.setPageNum(1);
        cebUploadReqRequest.setPageSize(5);
        CommonPage commonPage = cebUploadReqService.getCebUploadReqList(cebUploadReqRequest);
        List<CebUploadReqResponse> cebUploadReqResponseList = commonPage.getList();
        List<CebUnSendDataResp> cebUnSendDataRespList = cebUploadReqResponseList.stream().map(item -> {
            CebUnSendDataResp cebUnSendDataResp = new CebUnSendDataResp();
            cebUnSendDataResp.setSessionId(item.getSessionId());
            return cebUnSendDataResp;
        }).collect(Collectors.toList());
        return CommonResult.success(cebUnSendDataRespList);
    }

    /**
     * 上传海关实时数据
     * @param sessionID
     * @param isTest
     * @return
     */
    @GetMapping("/client/realTimeDataUpload")
    public CommonResult realTimeDataUpload(@RequestParam String sessionID,@RequestParam boolean isTest) {
        log.info("sessionID={}", sessionID);
        CebUploadReqResponse cebUploadReqResponse=cebUploadReqService.findBySessionId(sessionID);
        if(null==cebUploadReqResponse){
            return CommonResult.failed("sessionID不存在！");
        }
        if(CebUploadReqSignStatusEnums.UN_SIGN.getStatus().equals(cebUploadReqResponse.getSignStatus())){
            return CommonResult.failed("该数据未加签！");
        }
        CebOrderResponse cebOrder=cebOrderService.findByOrderNo(cebUploadReqResponse.getOrderNo());
        if(cebOrder==null){
            return CommonResult.failed("订单不存在！");
        }
        PayExInfoVO payExInfoVO=new PayExInfoVO();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        PayExchangeInfoHeadVO payExchangeInfoHead = new PayExchangeInfoHeadVO();
        payExchangeInfoHead.setCurrency("142");
        payExchangeInfoHead.setEbpCode(cebParamConfig.getEbpCode());
        payExchangeInfoHead.setGuid(cebOrder.getGuid());
        payExchangeInfoHead.setInitalRequest(cebOrder.getInitalRequest());
        payExchangeInfoHead.setInitalResponse(cebOrder.getInitalResponse());
        payExchangeInfoHead.setNote(cebOrder.getNote());
        payExchangeInfoHead.setPayCode(cebOrder.getPayCode());
        payExchangeInfoHead.setPayTransactionId(cebOrder.getPayTransactionId());
        payExchangeInfoHead.setPayType(String.valueOf(cebOrder.getPayType()));
        payExchangeInfoHead.setTotalAmount(cebOrder.getTotalAmount().doubleValue());
        payExchangeInfoHead.setTradingTime(sdf.format(cebOrder.getTradingTime()));
        payExchangeInfoHead.setVerDept(cebOrder.getVerDept());
        List<PayExchangeInfoVO> payExchangeInfoList = new ArrayList<>();
        PayExchangeInfoVO payExchangeInfoVO = new PayExchangeInfoVO();
        List<GoodsInfoVO> goodsInfoVOList = new ArrayList<>();
        for(CebOrderGoodsResponse goodsResponse:cebOrder.getCebOrderGoodsList()){
            GoodsInfoVO goodsInfoVO = new GoodsInfoVO();
            goodsInfoVO.setGname(goodsResponse.getItemName());
            goodsInfoVO.setItemLink(goodsResponse.getItemLink());
            goodsInfoVOList.add(goodsInfoVO);
        }
        payExchangeInfoVO.setGoodsInfo(goodsInfoVOList);
        payExchangeInfoVO.setOrderNo(cebOrder.getOrderNo());
        payExchangeInfoVO.setRecpAccount(cebOrder.getRecpAccount());
        payExchangeInfoVO.setRecpCode(cebOrder.getRecpCode());
        payExchangeInfoVO.setRecpName(cebOrder.getRecpName());
        payExchangeInfoList.add(payExchangeInfoVO);
        payExInfoVO.setPayExchangeInfoHead(payExchangeInfoHead);
        payExInfoVO.setPayExchangeInfoLists(payExchangeInfoList);
        payExInfoVO.setSessionID(sessionID);
        payExInfoVO.setCertNo(cebParamConfig.getCertNo());
        payExInfoVO.setSignValue(cebUploadReqResponse.getSignValue());
        payExInfoVO.setServiceTime(cebUploadReqResponse.getServiceTime());
        CebDataUploadResp cebDataUploadResp=CebUtil.realTimeDataUpload(payExInfoVO,isTest);
        if(cebDataUploadResp!=null&&"10000".equals(cebDataUploadResp.getCode())){
            log.info("sessionID:{}上报海关成功！",sessionID);
            cebUploadReqService.updateStatus(cebUploadReqResponse.getId(),CebUploadReqStatusEnums.SUCCESS.getStatus(),new Date());
            return CommonResult.success(JSONObject.toJSONString(cebDataUploadResp));
        }else{
            log.error("sessionID:{}上报海关失败！错误信息:{}",sessionID,JSONObject.toJSONString(cebDataUploadResp));
            cebUploadReqService.updateStatus(cebUploadReqResponse.getId(),CebUploadReqStatusEnums.FAIL.getStatus(),new Date());
            return CommonResult.failed(JSONObject.toJSONString(cebDataUploadResp));
        }
    }
}
